using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Org.BouncyCastle.Asn1.Cmp;
using WorkOrder.Contexts;
using WorkOrder.Extensions;
using WorkOrder.Interfaces;
using WorkOrder.Models;
using  BootstrapBlazor.Components;
 
namespace WorkOrder.Services;

/// <summary>
/// 工作订单服务类，实现了 <see cref="IWorkOrderService"/> 接口。
/// </summary>
public class WorkOrderService(IDbContextFactory<WorkOrderContext> contextFactory) : IWorkOrderService
{
    private readonly IDbContextFactory<WorkOrderContext> _contextFactory = contextFactory;
 

public async Task<List<模板字段表>> GetTemplates(string 模板ID)
{
    using var context = _contextFactory.CreateDbContext();
    return  await context.工单模板详情s.Where(cm=>cm.模板ID==模板ID).ToListAsync();
}
   #region 账户余额操作
        private async Task HandleBalanceAsync(
            string userId,
            decimal amount,
            WorkOrderContext context,
            BalanceOperation operation,
            string  operatorId,
            string relatedBusinessId = null,  // 可选业务ID
            string customRemark = null)
        {
            var userAccount = await context.用户账户余额表s
                .FirstOrDefaultAsync(u => u.用户ID == userId) 
                ?? throw new InvalidOperationException("用户账户不存在");

            // 根据操作类型处理业务逻辑
            switch (operation)
            {
                case BalanceOperation.Freeze:
                    if (userAccount.当前余额 < amount)
                        throw new InvalidOperationException("余额不足，无法冻结");
                    userAccount.当前余额 -= amount;
                    userAccount.冻结金额 += amount;
                    // CreateFlowRecord(FlowType.冻结, -amount,operatorId); // 只记录解冻流水
                    break;

                case BalanceOperation.Deduct:
                    if (userAccount.冻结金额 < amount)
                        throw new InvalidOperationException("冻结金额不足，无法扣除");
                    userAccount.冻结金额 -= amount;
                    CreateFlowRecord(FlowType.消费, -amount,operatorId); // 只记录扣款流水
                    break;

                case BalanceOperation.Recharge:
                    userAccount.当前余额 += amount;
                    CreateFlowRecord(FlowType.充值, amount,operatorId); // 记录充值流水
                    break;

                case BalanceOperation.Unfreeze:
                    if (userAccount.冻结金额 < amount)
                        throw new InvalidOperationException("冻结金额不足，无法解冻");
                    userAccount.冻结金额 -= amount;
                    userAccount.当前余额 += amount;
                    // CreateFlowRecord(FlowType.解冻, amount,operatorId); // 只记录解冻流水
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(operation));
            }

            // 公共字段更新
            userAccount.最后更新时间 = DateTime.Now;
            await context.SaveChangesAsync();

            // 内部流水记录方法
            void CreateFlowRecord(FlowType flowType, decimal signedAmount,string operatorId)
            {
                context.资金流水表s.Add(new 资金流水表
                {
                    用户ID = userId,
                    变动金额 = signedAmount,
                    流水类型 = flowType,
                    关联业务ID = relatedBusinessId,
                    交易状态 = FlowStatus.SUCCESS,
                    创建时间 = DateTime.Now,
                    备注 = customRemark ?? GetDefaultRemark(flowType),
                    操作人ID=operatorId
                });
            }

            string GetDefaultRemark(FlowType type) => type switch
            {
                FlowType.消费 => $"业务扣款：{amount}",
                FlowType.冻结 => $"业务冻结：{amount}",

                FlowType.解冻 => $"业务解冻：{amount}",
                FlowType.充值 => $"账户充值：{amount}",
                _ => string.Empty
            };
        }

    public enum BalanceOperation
    {
        Freeze,     // 冻结
        Deduct,      // 扣款
        Unfreeze,   // 解冻
        Recharge    // 充值（新增）
    }


    #endregion

 


    #region 分配工作订单
    /// <summary>
    /// 分配工作订单。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <param name="assigneeId">被分配人ID。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="comment">备注。</param>
    /// <returns>异步任务。</returns>
    public async Task AssignWorkOrderAsync(string workOrderId, string assigneeId, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        var workOrder = await context.工单主表s.FirstOrDefaultAsync(cm => cm.工单id == workOrderId);
        if (workOrder == null)
        {
            return;
        }

        var assignment = new 工单分派记录表
        {
            工单id = workOrderId,
            用户id = assigneeId,
            分派类型 = AssignmentType.主要,
            开始时间 = DateTime.Now,
            是否当前负责人 = true,
            分派说明 = comment
        };

        context.工单分派记录表s.Add(assignment);
        await context.SaveChangesAsync();
    }
    #endregion

    #region 完成工单并扣款
    /// <summary>
    /// 完成工单并扣款
    /// </summary>
    /// <param name="workOrderId">工单ID</param>
    /// <returns></returns>
    public async Task CompleteWorkOrderAndDeductAsync(string workOrderId, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
        try
        {
            // 1. 获取工单
            var workOrder = await context.工单主表s.Include(w =>w.工单附件表s)
                .FirstOrDefaultAsync(w => w.工单id == workOrderId);

            if (workOrder == null)
            {
                throw new InvalidOperationException("工单不存在");
            }

            // 2. 检查工单状态是否为“进行中”
            if (workOrder.当前状态 != WorkOrderStatus.处理中)
            {
                throw new InvalidOperationException("工单状态异常，无法完成");
            }
            // 4. 检查冻结金额是否足够
            await HandleBalanceAsync(workOrder.创建人id, workOrder.总金额 ?? 0, context, BalanceOperation.Deduct, operatorId, relatedBusinessId: workOrderId);
            

            if (workOrder.工单附件表s != null && workOrder.工单附件表s.Count > 0)
            {
                foreach (var attachment in workOrder.工单附件表s)
                {
                   attachment.是否提交=true;
                }
            }
            // 5 更新工单状态为“已完成”
            workOrder.当前状态 = WorkOrderStatus.已解决;
            workOrder.关闭时间 = DateTime.Now;
             var logDetails = new
            {
                workOrder.工单编号,
                处理人=operatorId,
            };
            var individualLogDetails = GenerateLogDetails("工单已解决", logDetails, comment);
            var log = new 工单操作日志表
                    {
                        工单id = workOrderId,
                        操作人id = operatorId,
                        操作类型 = OperationType.解决,
                        操作详情 = individualLogDetails,
                        操作时间 = DateTime.Now
                    };

            context.工单操作日志表s.Add(log);
            // 8. 保存更改
            await context.SaveChangesAsync();
            await TransitionToNextNodeAsync(workOrderId,"系统",context); // 转移到下一个节点
            await transaction.CommitAsync();

       
        }
        catch
        {
            await transaction.RollbackAsync();
            throw;
        }
    }
    #endregion


    #region 关闭工作订单
    /// <summary>
    /// 关闭工作订单。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="comment">备注。</param>
    /// <returns>异步任务。</returns>
    public async Task CloseWorkOrderAsync(string workOrderId, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
       try{
             var workOrder = await context.工单主表s.FindAsync(workOrderId);
        if (workOrder == null)
        {
            return;
        }
        await HandleBalanceAsync(workOrder.创建人id, workOrder.总金额 ?? 0, context, BalanceOperation.Unfreeze, operatorId, relatedBusinessId: workOrderId);
        workOrder.当前状态 = WorkOrderStatus.已关闭;
        workOrder.关闭时间 = DateTime.Now;

        var log = new 工单操作日志表
        {
            工单id = workOrderId,
            操作人id = operatorId,
            操作类型 = OperationType.关闭,
            操作详情 = comment,
            操作时间 = DateTime.Now
        };        
        context.工单操作日志表s.Add(log);
        await context.SaveChangesAsync();
        await TransitionToNextNodeAsync(workOrderId,operatorId,context,false); // 转移到下一个节点
       
        await transaction.CommitAsync();
           
         }
        catch
        {
            await transaction.RollbackAsync();
            throw;
        }
    }

    
    
    #endregion


    #region 批量创建工单
    public async Task<List<工单主表>> BatchCreateWorkOrdersAsync(
    string templateId,
    List<Dictionary<string, object>> workOrders,
    string? title,
    string? description,
    string 创建人ID,
    string 流程ID)
    {
        using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
        try
        {   
             var workflot = await context.流程配置表s
                .Include(t => t.节点列表)
                .FirstOrDefaultAsync(t => t.流程ID == 流程ID);

            if (workflot == null)
            {
                throw new ArgumentException("流程不存在", nameof(流程ID));
            }

            var template = await context.工单模板s
                .Include(t => t.字段定义)
                .FirstOrDefaultAsync(t => t.模板ID == templateId);

            if (template == null)
            {
                throw new ArgumentException("模板不存在", nameof(templateId));
            }

            var createdWorkOrders = new List<工单主表>();
            decimal Amount = 0;
            foreach (var workOrderData in workOrders)
            {
                // 验证工单数据
                foreach (var field in template.字段定义)
                {
                    if (field.是否必填 && (!workOrderData.ContainsKey(field.字段名称) || workOrderData[field.字段名称] == null))
                    {
                        throw new ArgumentException($"字段 {field.字段名称} 是必填项");
                    }
                    if (field.是否核心字段)
                    {
                        Amount = decimal.TryParse(workOrderData[field.字段名称]?.ToString(), out decimal value) ? value : 0;
                    }
                }

                // 创建工单实体
                var workOrder = new 工单主表
                {
                    模板ID = templateId,
                    工单标题 = title ?? "未命名工单",
                    问题描述 = description ?? "",
                    扩展字段 = workOrderData,
                    创建时间 = DateTime.Now,
                    更新时间 = DateTime.Now,
                    当前状态 = WorkOrderStatus.待处理,
                    创建人id = 创建人ID,// 设置创建人ID
                    总金额 = Amount
                };

                // 调用单个工单创建方法
                var createdWorkOrder = await CreateWorkOrderAsync(workOrder, context, 流程ID);
                createdWorkOrders.Add(createdWorkOrder);
                await TransitionToNextNodeAsync(createdWorkOrder.工单id,"系统",context); // 转移到下一个节点
            }

            await transaction.CommitAsync();
            return createdWorkOrders;
        }
        catch
        {
            await transaction.RollbackAsync();
            throw;
        }
        // 获取模板信息

    }

    #endregion
    #region  给用户充值
    public async Task RechargeUserBalanceAsync(
    string userId, 
    decimal amount, 
     string operatorId,
    string relatedBusinessId = null, 
    string customRemark = null
   )
{
    using var context = _contextFactory.CreateDbContext();
    using var transaction = await context.Database.BeginTransactionAsync();
    try
    {


                // 获取用户账户，如果不存在则创建
        var userAccount = await context.用户账户余额表s
            .FirstOrDefaultAsync(u => u.用户ID == userId);

        if (userAccount == null)
        {
            userAccount = new 用户账户余额表
            {
                用户ID = userId,
                当前余额 = 0,
                冻结金额 = 0,
                最后更新时间 = DateTime.Now
            };
            context.用户账户余额表s.Add(userAccount);
            await context.SaveChangesAsync();
        }

        // 调用 HandleBalanceAsync 方法进行充值
        await HandleBalanceAsync(
            userId: userId,
            amount: amount,
            context: context,
            operation: BalanceOperation.Recharge, // 充值操作
            relatedBusinessId:  null, // 关联业务ID（可选）
            customRemark: customRemark ?? $"用户充值：{amount}",
            operatorId: operatorId
             // 自定义备注（可选）
        );
        await transaction.CommitAsync();
    }
     catch (Exception ex)
    {  
        // Console.WriteLine($"充值过程中发生未知错误：{ex.Message}");
        await transaction.RollbackAsync();
        throw;
    }
    
}
  #endregion

    #region 创建工作订单单个
    /// <summary>
    /// 创建工作订单。
    /// </summary>
    /// <param name="workOrder">工作订单实体。</param>
    /// <returns>异步任务，包含创建的工作订单。</returns>
    public async Task<工单主表> CreateWorkOrderAsync(工单主表 workOrder, string processId)
    {
        using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
        try{
            
        // 生成工单编号
        NewWorkOrderID(workOrder);
     
        // 保存工单
        context.工单主表s.Add(workOrder);
        await context.SaveChangesAsync();
        await HandleBalanceAsync(workOrder.创建人id, workOrder.总金额 ?? 0, context, BalanceOperation.Freeze,"System",workOrder.工单id); 
        var processTemplate = await context.流程配置表s
            .Include(p => p.节点列表)
            .FirstOrDefaultAsync(p => p.流程ID == processId) ?? throw new InvalidOperationException("流程模板不存在");
            var startNode = processTemplate.节点列表.FirstOrDefault(n => n.操作类型 ==  OperationType.创建) ?? throw new InvalidOperationException("流程模板中缺少起始节点");
            var processInstance = new 工单流程实例表
        {
            工单ID = workOrder.工单id,
            流程ID = processTemplate.流程ID,
            当前节点ID = startNode.节点ID,
            状态 = WorkOrderStatus.待处理,
            创建时间 = DateTime.Now,
            更新时间 = DateTime.Now,
        
        };
        context.工单流程实例表s.Add(processInstance);
         await context.SaveChangesAsync();
        // 记录日志
        var logDetails = new
        {
            workOrder.工单编号,
            workOrder.创建人id,
        };
        var individualLogDetails = GenerateLogDetails("工单创建", logDetails, "创建新的工单");
        await LogWorkOrderOperationAsync(workOrder.工单id, workOrder.创建人id ?? "系统", OperationType.创建, individualLogDetails, context);
        await transaction.CommitAsync();
        return workOrder;
    }
    catch
    {
        await transaction.RollbackAsync();
        throw;
    }

    }
    #endregion

    #region 创建工作订单单个
    /// <summary>
    /// 创建工作订单。
    /// </summary>
    /// <param name="workOrder">工作订单实体。</param>
    /// <returns>异步任务，包含创建的工作订单。</returns>
    private async Task<工单主表> CreateWorkOrderAsync(工单主表 workOrder, WorkOrderContext context, string processId)
    {
      

  
        NewWorkOrderID(workOrder);
      
        // 保存工单
        context.工单主表s.Add(workOrder);
        await context.SaveChangesAsync();
        await HandleBalanceAsync(workOrder.创建人id, workOrder.总金额 ?? 0, context, BalanceOperation.Freeze,"System", workOrder.工单id); 
        var processTemplate = await context.流程配置表s
            .Include(p => p.节点列表)
            .FirstOrDefaultAsync(p => p.流程ID == processId);

        if (processTemplate == null)
        {
            throw new InvalidOperationException("流程模板不存在");
        }
        var startNode = processTemplate.节点列表.FirstOrDefault(n => n.操作类型 ==  OperationType.创建);
        if (startNode == null)
        {
            throw new InvalidOperationException("流程模板中缺少起始节点");
        }
        var processInstance = new 工单流程实例表
        {
            工单ID = workOrder.工单id,
            流程ID = processTemplate.流程ID,
            当前节点ID = startNode.节点ID,
            状态 = WorkOrderStatus.待处理,
            创建时间 = DateTime.Now,
            更新时间 = DateTime.Now
        };
        context.工单流程实例表s.Add(processInstance);
         await context.SaveChangesAsync();
        // 记录日志
        var logDetails = new
        {
            workOrder.工单编号,
            workOrder.创建人id,
        };
        var individualLogDetails = GenerateLogDetails("工单创建", logDetails, "创建新的工单");
        await LogWorkOrderOperationAsync(workOrder.工单id, workOrder.创建人id ?? "系统", OperationType.创建, individualLogDetails, context);
        return workOrder;

    }
    #endregion



    private static void NewWorkOrderID(工单主表 workOrder)
    {
        var datePart = DateTime.Now.ToString("yyyyMMdd");
        var guidPart = Guid.NewGuid().ToString("N").Substring(0, 8); // 取 GUID 的前 8 位
        workOrder.工单编号 = $"Ticket{datePart}-{guidPart}";
    }





    #region 删除工作订单
    /// <summary>
    /// 删除工作订单。
    /// </summary>
    /// <param name="workOrderId">工单号</param>
    /// <param name="operatorId">操作人</param>
    /// <param name="comment">备注</param>
    /// <returns></returns>
    public async Task DeleteWorkOrderAsync(string workOrderId, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        var workOrder = await context.工单主表s.FirstOrDefaultAsync(cm => cm.工单id == workOrderId);
        if (workOrder == null)
        {
            return;
        }

        workOrder.是否显示 = false;

        await context.SaveChangesAsync();
        var logDetails = new
        {
            workOrder.工单编号,
            操作人ID = operatorId,
        };
        var individualLogDetails = GenerateLogDetails("工单被删除", logDetails, comment);
        await LogWorkOrderOperationAsync(workOrderId, operatorId, OperationType.关闭, individualLogDetails);
    }
    #endregion

    #region 获取子工作订单
    /// <summary>
    /// 获取子工作订单。
    /// </summary>
    /// <param name="parentWorkOrderId">父工作订单ID。</param>
    /// <returns>异步任务，包含子工作订单集合。</returns>
    public async Task<IEnumerable<工单主表>> GetChildWorkOrdersAsync(string parentWorkOrderId)
    {
        using var context = _contextFactory.CreateDbContext();
        return await context.工单主表s.Where(cm => cm.父工单id == parentWorkOrderId).ToListAsync();
    }
    #endregion

    #region 根据ID获取工作订单
    /// <summary>
    /// 根据ID获取工作订单。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <returns>异步任务，包含工作订单实体。</returns>
    public async Task<工单主表> GetWorkOrderByIdAsync(string workOrderId)
    {
        using var context = _contextFactory.CreateDbContext();
        var workOrder = await context.工单主表s
        .Include(w => w.工单附件表s)
        .Include(w => w.工单评论表s)
        .Include(w => w.工单分派记录表s)
        .Include(w => w.工单操作日志表s)
        .Include(w => w.关联模板)
        .Include(w => w.关联模板.字段定义)
        .FirstOrDefaultAsync(cm => cm.工单id == workOrderId);
        if (workOrder == null)
        {
            return null;
        }

        return workOrder;
    }
    #endregion

    #region 重新打开工作订单
    /// <summary>
    /// 重新打开工作订单。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="comment">备注。</param>
    /// <returns>异步任务。</returns>
    public async Task ReopenWorkOrderAsync(string workOrderId, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        var workOrder = await context.工单主表s.FindAsync(workOrderId);
        if (workOrder == null)
        {
            return;
        }

        workOrder.当前状态 = WorkOrderStatus.重新打开;


        await context.SaveChangesAsync();
        var logDetails = new
        {
            workOrder.工单编号,
            操作人ID = operatorId,
        };
        var individualLogDetails = GenerateLogDetails("工单重新打开", logDetails, comment);
        await LogWorkOrderOperationAsync(workOrderId, operatorId, OperationType.重新打开, individualLogDetails);

    }
    #endregion

    #region 转移工作订单
    /// <summary>
    /// 转移工作订单。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <param name="fromUserId">转移前用户ID。</param>
    /// <param name="toUserId">转移后用户ID。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="comment">备注。</param>
    /// <returns>异步任务。</returns>
    public async Task TransferWorkOrderAsync(string workOrderId, string fromUserId, string toUserId, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        var workOrder = await context.工单主表s.FindAsync(workOrderId);
        if (workOrder == null)
        {
            return;
        }

        var assignment = new 工单分派记录表
        {
            工单id = workOrderId,
            用户id = toUserId,
            分派类型 = AssignmentType.主要,
            开始时间 = DateTime.Now,
            是否当前负责人 = true,
            分派说明 = comment
        };

        context.工单分派记录表s.Add(assignment);
        await context.SaveChangesAsync();
    }
    #endregion

    #region 更新工作订单
    /// <summary>
    /// 更新工作订单。
    /// </summary>
    /// <param name="workOrder">工作订单实体。</param>
    /// <returns>异步任务。</returns>
    public async Task UpdateWorkOrderAsync(工单主表 workOrder)
    {
        using var context = _contextFactory.CreateDbContext();
        context.工单主表s.Update(workOrder);
        await context.SaveChangesAsync();
    }
    #endregion

    #region 拆分工作订单
    /// <summary>
    /// 拆分工作订单。
    /// </summary>
    /// <param name="parentWorkOrderId">父工作订单ID。</param>
    /// <param name="newWorkOrders">新工作订单实体集合。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="comment">备注。</param>
    /// <returns>异步任务，包含创建的子工作订单集合。</returns>
    public async Task<IEnumerable<工单主表>> SplitWorkOrderAsync(string parentWorkOrderId, IEnumerable<工单主表> newWorkOrders, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        var parentWorkOrder = await context.工单主表s.FindAsync(parentWorkOrderId);
        if (parentWorkOrder == null)
        {
            throw new ArgumentException("父工作订单不存在", nameof(parentWorkOrderId));
        }

        var parentWorkOrderNumber = parentWorkOrder.工单编号;
        var existingChildCount = await context.工单主表s.CountAsync(wo => wo.父工单id == parentWorkOrderId);
        var createdWorkOrders = new List<工单主表>();
        int childOrderIndex = existingChildCount + 1;

        foreach (var newWorkOrder in newWorkOrders)
        {
            newWorkOrder.父工单id = parentWorkOrderId;
            newWorkOrder.根工单id = parentWorkOrder.根工单id ?? parentWorkOrderId;
            newWorkOrder.创建时间 = DateTime.Now;
            newWorkOrder.更新时间 = DateTime.Now;
            newWorkOrder.工单编号 = $"{parentWorkOrderNumber}-{childOrderIndex++}";

            context.工单主表s.Add(newWorkOrder);
            createdWorkOrders.Add(newWorkOrder);
        }

        await context.SaveChangesAsync();

        var individualLogDetails = new { orderlist = createdWorkOrders.Select(wo => wo.工单编号).ToArray() };

        await LogWorkOrderOperationAsync(parentWorkOrderId, operatorId, OperationType.拆分, GenerateLogDetails("工单拆分", individualLogDetails, comment));

        return createdWorkOrders;
    }
    #endregion

    #region 记录操作日志
    /// <summary>
    /// 记录操作日志。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="operationType">操作类型。</param>
    /// <param name="details">操作详情。</param>
    /// <returns>异步任务。</returns>
    private async Task LogWorkOrderOperationAsync(string workOrderId, string operatorId, OperationType operationType, string details)
    {
        using var context = _contextFactory.CreateDbContext();
        var log = new 工单操作日志表
        {
            工单id = workOrderId,
            操作人id = operatorId,
            操作类型 = operationType,
            操作详情 = details,
            操作时间 = DateTime.Now
        };

        context.工单操作日志表s.Add(log);
        await context.SaveChangesAsync();
    }

    private async Task LogWorkOrderOperationAsync(string workOrderId, string operatorId, OperationType operationType, string details, WorkOrderContext context)
    {

        var log = new 工单操作日志表
        {
            工单id = workOrderId,
            操作人id = operatorId,
            操作类型 = operationType,
            操作详情 = details,
            操作时间 = DateTime.Now
        };

        context.工单操作日志表s.Add(log);
        await context.SaveChangesAsync();
    }
    #endregion

    #region 生成日志详情
    private string GenerateLogDetails(string operationType, object details, string comment)
    {
        var logDetails = new Dictionary<string, object>
        {
            { operationType, details },
            {"备注", comment }
        };
        return JsonSerializer.Serialize(logDetails,JsonConfig.JsonOptions);
    }
    #endregion

    #region 分配工作订单给多个用户
    /// <summary>
    /// 分配工作订单给多个用户。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <param name="assigneeIds">被分配人ID集合。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="comment">备注。</param>
    /// <returns>异步任务。</returns>
    public async Task AssignWorkOrderAsync(string workOrderId, IEnumerable<string> assigneeIds, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        var workOrder = await context.工单主表s.FirstOrDefaultAsync(cm => cm.工单id == workOrderId);
        if (workOrder == null)
        {
            return;
        }
 
        var existingAssignees = (await context.工单分派记录表s
            .Where(a => a.工单id == workOrderId)
            .Select(a => a.用户id)
            .ToListAsync())
            .Where(id => assigneeIds.Contains(id))
            .ToList();

        foreach (var assigneeId in assigneeIds.Except(existingAssignees))
        {
            var assignment = new 工单分派记录表
            {
                工单id = workOrderId,
                用户id = assigneeId,
                分派类型 = AssignmentType.主要,
                开始时间 = DateTime.Now,
                是否当前负责人 = true,
                分派说明 = comment
            };

            context.工单分派记录表s.Add(assignment);
        }

        await context.SaveChangesAsync();
    }
    #endregion

    #region 变更工作订单处理人
    /// <summary>
    /// 变更工作订单处理人。
    /// </summary>
    /// <param name="workOrderId">工作订单ID。</param>
    /// <param name="newAssigneeIds">新的处理人ID集合。</param>
    /// <param name="operatorId">操作人ID。</param>
    /// <param name="comment">备注。</param>
    /// <returns>异步任务。</returns>
    public async Task ChangeAssigneeAsync(string workOrderId, IEnumerable<string> newAssigneeIds, string operatorId, string comment)
    {
        using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
        try{
              var workOrder = await context.工单主表s.FirstOrDefaultAsync(cm => cm.工单id == workOrderId);
        if (workOrder == null)
        {
            return;
        }



        // 获取当前的处理人记录
        var currentAssignments = await context.工单分派记录表s
            .Where(a => a.工单id == workOrderId && a.是否当前负责人.Value)
            .ToListAsync();


        if (currentAssignments.Select(a => a.用户id).SequenceEqual(newAssigneeIds))
        {
            return;
        }
        // 更新现有的处理人记录，将其是否当前负责人字段设置为false
        foreach (var assignment in currentAssignments)
        {
            assignment.是否当前负责人 = false;
            assignment.结束时间 = DateTime.Now;
        }

        // 如果没有处理人发生变更，则直接返回



        var newBatchId = Guid.NewGuid().ToString();
        // 添加新的处理人记录
        foreach (var newAssigneeId in newAssigneeIds)
        {
            var newAssignment = new 工单分派记录表
            {
                工单id = workOrderId,
                用户id = newAssigneeId,
                分派类型 = AssignmentType.主要,
                开始时间 = DateTime.Now,
                是否当前负责人 = true,
                分派说明 = comment,
                分派操作人 = operatorId,
                分派批次id = newBatchId,

            };
            workOrder.当前状态=WorkOrderStatus.已分派;
            context.工单分派记录表s.Add(newAssignment);
        }

        // 记录变更处理人
        var logDetails = new
        {
            workOrder.工单编号,
            操作人ID = operatorId,
            新处理人IDs = newAssigneeIds
        };
        var individualLogDetails = GenerateLogDetails("变更处理人", logDetails, comment);

        await context.SaveChangesAsync();
        await LogWorkOrderOperationAsync(workOrderId, operatorId, OperationType.分派, individualLogDetails,context);
        await TransitionToNextNodeAsync(workOrderId,"系统",context); // 转移到下一个节点
        await transaction.CommitAsync();
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();
            throw new InvalidOperationException("变更处理人失败", ex);
        }
 
      
    }
    #endregion

    #region 获取当前已接待处理人本人还没完成的工单
    /// <summary>
    /// 获取当前已接待处理人本人还没完成的工单。
    /// </summary>
    /// <param name="assigneeId">处理人ID。</param>
    /// <returns>异步任务，包含未完成的工单集合。</returns>
    public async Task<IEnumerable<工单主表>> GetPendingWorkOrdersByAssigneeAsync(string assigneeId)
    {
        using var context = _contextFactory.CreateDbContext();
        return await context.工单主表s
            .Where(wo => wo.当前状态 != WorkOrderStatus.已关闭 &&
                        context.工单分派记录表s.Any(a => a.工单id == wo.工单id &&
                                                        a.用户id == assigneeId &&
                                                        a.是否当前负责人 == true))
            .ToListAsync();
    }
    #endregion

    #region  获取当前工单操作日志
    /// <summary>
    /// 获取当前已接待处理人本人还没完成的工单。
    /// </summary>
    /// <param name="assigneeId">处理人ID。</param>
    /// <returns>异步任务，包含未完成的工单集合。</returns>
    public async Task<IEnumerable<工单操作日志表>> GetWorkOrderslog(string workOrderID)
    {
        using var context = _contextFactory.CreateDbContext();
        return  await context.工单操作日志表s.Where(wo => wo.工单id == workOrderID).OrderBy(cm=>cm.操作时间).ToListAsync();

    }
    #endregion

    public   async Task<List<工单全信息视图>> GetWorkOrdersAsync()
    { 
        
        using var context = _contextFactory.CreateDbContext();
        return   await  context.工单全信息视图s.ToListAsync();
    }

    /// <summary>
    /// 获取当前登录用户的工单列表。
    /// 返回当前用户为处理人的订单
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>
    public async Task<List<工单全信息视图>> GetWorkOrdersForUserAsync(string user, WorkOrderStatus? workOrderStatus=null)
    {
        using var context = _contextFactory.CreateDbContext();

        return await context.工单全信息视图s
            .Where(cm => cm.负责人id列表.Contains(user) && 
                         (!workOrderStatus.HasValue || cm.当前状态 == workOrderStatus))
                         
            .ToListAsync();
    }
    public async Task<List<工单全信息视图>> GetWorkOrdersForUserCompletedAsync(string user)
    {


        using var context = _contextFactory.CreateDbContext();
        return await context.工单全信息视图s.Where(cm => cm.负责人id列表.Contains(user) && (cm.当前状态 == WorkOrderStatus.已关闭||cm.当前状态 ==WorkOrderStatus.已解决) ).ToListAsync();


    }
    /// <summary>
    /// 获取当前登录用户的工单列表。
    /// 返回当前用户为创建人的订单
    /// 该方法会返回所有工单，包括已完成和未完成的工单。
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>
    public   async Task<List<工单全信息视图>> GetWorkOrdersForMeAsync(string user)
    { 
        
        using var context = _contextFactory.CreateDbContext();
        return   await  context.工单全信息视图s.Where(cm=>cm.创建人ID==user).ToListAsync();
    }


 public async Task<List<工单全信息视图>> GetWorkOrdersForAuditorAsync(List<string> roles)
{
    // var roleList = roles.ToList(); // 确保是具体化的 List
    // using var context = _contextFactory.CreateDbContext();
    // return await context.工单全信息视图s
    //     .Where(cm => roleList.Any(role => role == cm.当前节点权限))
    //     .ToListAsync();
 
    if (!roles.Any())
        return new List<工单全信息视图>();

    using var context = _contextFactory.CreateDbContext();
    var query = context.工单全信息视图s.Where(cm => cm.当前节点权限 == roles[0]);
    
    foreach (var role in roles.Skip(1))
    {
        var currentRole = role; // 避免闭包问题
        query = query.Union(context.工单全信息视图s.Where(cm => cm.当前节点权限 == currentRole));
    }
    
    return await query.ToListAsync();
 


}



    public   async Task<List<当前分派视图>> GetHandler(string workOrderID)
    { 
        
        using var context = _contextFactory.CreateDbContext();
        return   await  context.当前分派视图s.Where(cm=>cm.工单id==workOrderID).ToListAsync();
    }
    public async Task<工单模板表?> GetTemplateByIdAsync(string templateId)
    {
    using var context = _contextFactory.CreateDbContext();
        return await context.工单模板s
            .Include(t => t.字段定义)
            .FirstOrDefaultAsync(t => t.模板ID == templateId);
    }
    public   async Task<List<用户账户余额表>> GetRecharge()
    { 
        
        using var context = _contextFactory.CreateDbContext();
        return   await  context.用户账户余额表s.ToListAsync();
    }

    public async Task<List<资金流水表>> GetFlow(string UserName)
    {
        using var context = _contextFactory.CreateDbContext();
        return await context.资金流水表s.Where(cm=>cm.用户ID==UserName).ToListAsync();
    }

     public async Task<List<资金流水表>> GetFlowforTime(DateTime startDate, DateTime endDate)
    {
        using var context = _contextFactory.CreateDbContext();
        return await context.资金流水表s.Where(cm=>cm.创建时间<=endDate&&cm.创建时间>=startDate).ToListAsync();
    }


    public async Task<List<工单模板表>> GetTemplateList()
    {
        using var context = _contextFactory.CreateDbContext();
        return await context.工单模板s.Include(t => t.字段定义).ToListAsync();
    }
    public async Task<List<流程配置表>> GetProcessList(string? 流程ID = null)
    {
        using var context = _contextFactory.CreateDbContext();
        return await context.流程配置表s.Include(cm => cm.节点列表).Where(cm => string.IsNullOrEmpty(流程ID) || cm.流程ID == 流程ID).ToListAsync();
    }

    
    public async Task<工单流程实例表> GetProcessInstanceByWorkOrderIdAsync(string workOrderId)
    {
    using var context = _contextFactory.CreateDbContext();
    return await context.工单流程实例表s
    .Include(cm => cm.当前节点)
     .Include(cm => cm.当前节点.目标节点)
    .Include(cm => cm.当前节点.源节点)
    .Where(cm => cm.工单ID== workOrderId).FirstOrDefaultAsync();
    }
        public 工单流程实例表 GetProcessInstanceByWorkOrderId(string workOrderId)
            {
            using var context = _contextFactory.CreateDbContext();
            return   context.工单流程实例表s
            .Include(cm => cm.当前节点)
            .Include(cm => cm.当前节点.目标节点)
            .Include(cm => cm.当前节点.源节点)
            .Where(cm => cm.工单ID== workOrderId).FirstOrDefault();
            }

  public async Task<QueryData<TModel>> QueryTable<TModel>(QueryPageOptions option) where TModel : class, new()
    {
         using var context = _contextFactory.CreateDbContext();
        var ret = new  QueryData<TModel>
        {
            IsSorted = true,
            IsFiltered = true,
            IsSearch = true,
            IsAdvanceSearch = true
        };

        var filter = option.ToFilter();

        if (option.IsPage)
        {
            var pagedItems =  context.Set<TModel>()
                                .Where(filter.GetFilterLambda<TModel>(), filter.HasFilters())
                                .Sort(option.SortName!, option.SortOrder, !string.IsNullOrEmpty(option.SortName))
                                .Count(out var count)
                                .Page((option.PageIndex - 1) * option.PageItems, option.PageItems);
                                    
            ret.TotalCount = count;
            ret.Items =await pagedItems.ToListAsync();
        }
        else
        {
            var sortedItems =  context.Set<TModel>()
                                .Where(filter.GetFilterLambda<TModel>(), filter.HasFilters())
                                .Sort(option.SortName!, option.SortOrder, !string.IsNullOrEmpty(option.SortName))
                                .Count(out var count) ;

            ret.TotalCount = count;
            ret.Items =await sortedItems.ToListAsync();
        }

         return await Task.FromResult(ret);
    }


private async Task<流程节点表?> GetNextNodeAsync(流程节点表 currentNode, WorkOrderContext context,bool  isBatch = true)
{
    // 结束节点没有下一节点
    if (currentNode.节点类型 == NodeType.结束节点)
        return null;

    // 获取所有可能的下一节点路由
    var nextRoutes = await context.节点路由表s
        .Where(r => r.源节点ID == currentNode.节点ID)
        .Include(r => r.目标节点)
        .ToListAsync();

    if (!nextRoutes.Any())
        return null;

    // 如果是分支节点，需要评估条件
    if (currentNode.节点类型 == NodeType.分支节点)
    {
        foreach (var route in nextRoutes)
        {
            if (route.条件表达式.Value==isBatch) // 批量处理时，条件为空的路由直接返回
            {
                return route.目标节点;
            }
          
        }
        throw new InvalidOperationException("没有满足条件的分支");
    }

    // 普通节点直接返回第一个目标节点
    return nextRoutes.First().目标节点;
}
 private async Task TransitionToNextNodeAsync(string workOrderId, string operatorId, WorkOrderContext context,bool isBatch = true)
{
    var instance = await context.工单流程实例表s
        .Include(i => i.当前节点)
        .ThenInclude(n => n.源节点) // 包含节点路由关系
        .ThenInclude(r => r.目标节点)
        .Include(i => i.工单)
        .FirstOrDefaultAsync(i => i.工单ID == workOrderId) 
        ?? throw new InvalidOperationException("工单流程实例不存在");

    var currentNode = instance.当前节点;
    var nextNode = await GetNextNodeAsync(currentNode, context,isBatch);

    // 更新流程实例
    instance.当前节点ID = nextNode?.节点ID;
    instance.状态 = nextNode?.工单状态 ?? WorkOrderStatus.已解决;
    instance.更新时间 = DateTime.Now;

    // 更新工单状态
    instance.工单.当前状态 = nextNode?.工单状态 ?? WorkOrderStatus.已解决;
    if (nextNode == null)
    {
        instance.工单.关闭时间 = DateTime.Now;
    }

    await context.SaveChangesAsync();
    
    var logMessage = nextNode == null 
        ? $"流程结束，工单状态变更为{instance.工单.当前状态}"
        : $"从节点 [{currentNode.节点名称}] 流转到节点 [{nextNode.节点名称}]，状态变更为 {nextNode.工单状态}";
    
    await LogWorkOrderOperationAsync(
        workOrderId, 
        operatorId, 
        currentNode.操作类型, 
        logMessage, 
        context);
}


 public async Task TransitionToNextNodeAsync(string workOrderId, string operatorId,bool isBatch = true)
{
    using var context = _contextFactory.CreateDbContext();
    using var transaction = await context.Database.BeginTransactionAsync();
 try
    {
    var instance = await context.工单流程实例表s
        .Include(i => i.当前节点)
        .ThenInclude(n => n.源节点) // 包含节点路由关系
        .ThenInclude(r => r.目标节点)
        .Include(i => i.工单)
        .FirstOrDefaultAsync(i => i.工单ID == workOrderId) 
        ?? throw new InvalidOperationException("工单流程实例不存在");

    var currentNode = instance.当前节点;
    var nextNode = await GetNextNodeAsync(currentNode, context,isBatch);

    // 更新流程实例
    instance.当前节点ID = nextNode?.节点ID;
    instance.状态 = nextNode?.工单状态 ?? WorkOrderStatus.已解决;
    instance.更新时间 = DateTime.Now;

    // 更新工单状态
    instance.工单.当前状态 = nextNode?.工单状态 ?? WorkOrderStatus.已解决;
    if (nextNode == null||nextNode.节点类型==NodeType.结束节点)
    {
        instance.工单.关闭时间 = DateTime.Now;
    }

    await context.SaveChangesAsync();
    
    var logMessage = nextNode == null 
        ? $"流程结束，工单状态变更为{instance.工单.当前状态}"
        : $"从节点 [{currentNode.节点名称}] 流转到节点 [{nextNode.节点名称}]，状态变更为 {nextNode.工单状态}";
    
    await LogWorkOrderOperationAsync(
        workOrderId, 
        operatorId, 
        currentNode.操作类型, 
        logMessage, 
        context);
        await transaction.CommitAsync();

 }
    catch
    {
        await transaction.RollbackAsync();
        throw;
    }
}


 public async Task AddCommentAsync(CommentType commentType, string workOrderId, string operatorId, string text)
    {
             using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
        try{
 
        
        var comment = new 工单评论表
        {
            工单id = workOrderId,
            评论内容 = text,
            用户id = operatorId,
            评论类型= commentType,
        };

        context.工单评论表s.Add(comment);
        await context.SaveChangesAsync();
        await transaction.CommitAsync();
    }
    catch
    {
        await transaction.RollbackAsync();
        throw;
    }
    }
    public async Task AddFlieAsync(工单附件表  工单附件表)
    {
             using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
        try{
 
        
        
        context.工单附件表s.Add(工单附件表);
        await context.SaveChangesAsync();
        await transaction.CommitAsync();
    }
    catch
    {
        await transaction.RollbackAsync();
        throw;
    }
  
    }
    public async Task DeleteFlieAsync(string fileName,string  TicketID)
    {
        using var context = _contextFactory.CreateDbContext();
        using var transaction = await context.Database.BeginTransactionAsync();
     try{
        var file = await context.工单附件表s.FirstOrDefaultAsync(cm => cm.工单id == TicketID && cm.文件名 == fileName);
        if (file != null)
        {
            context.工单附件表s.Remove(file);
            await context.SaveChangesAsync();
        }
        await transaction.CommitAsync();
    }
    catch
    {
        await transaction.RollbackAsync();
        throw;
    }
  
    }

    public async Task<流程节点表?> GetRoute(string 节点ID)
    {
         using var context = _contextFactory.CreateDbContext();
        return  await context.流程节点表s.Where(cm => cm.节点ID == 节点ID).FirstOrDefaultAsync();
    }


    
}

